package com.dreamchaser.familydevice.support;


import com.alibaba.druid.util.StringUtils;
import com.dreamchaser.familydevice.annotation.CurrentUser;
import com.dreamchaser.familydevice.domain.dto.AccountDTO;
import com.dreamchaser.familydevice.domain.dto.JwtAccountDTO;
import com.dreamchaser.familydevice.exception.BusinessException;
import com.dreamchaser.familydevice.util.system.JsonWebTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 增加方法注入，将含有 @CurrentUser 注解的方法参数注入当前登录用户
 *
 * @author liugh
 * @since 2018-05-03
 */
@Slf4j
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(AccountDTO.class)
                && parameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public AccountDTO resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String jwt = (String) webRequest.getAttribute("currentUser", RequestAttributes.SCOPE_REQUEST);
        return get(jwt);
    }

    public AccountDTO get(String jwt) {
        if (StringUtils.isEmpty(jwt)) {
            throw new BusinessException("获取用户信息失败");
        }
        JwtAccountDTO jwtAccountDTO = null;
        try {
            jwtAccountDTO = JsonWebTokenUtil.parseJwt(jwt, JsonWebTokenUtil.SECRET_KEY);
        } catch (Exception e) {
            log.error("用户获取信息失败", e);
            throw new BusinessException("获取用户信息失败");
        }
        AccountDTO accountDTO = jwtAccountDTO.getAccount();
        if (accountDTO == null) {
            throw new BusinessException("获取用户信息失败");
        }
        return accountDTO;
    }

}
